/* 
 * cms，一个基于J2EE架构内容管理系统
 * Copyright © GrayRabbit Co., Ltd. All rights reserved.
 * Department:运营department
 * 更多信息请访问：
 * http://code.google.com/p/gray-rabbit-cms/
 */
package org.grayrabbit.cms.service.category.impl;
 
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.grayrabbit.cms.constant.DBInitId;
import org.grayrabbit.cms.constant.DictionaryStaticValues;
import org.grayrabbit.cms.dao.category.CategoryDao;
import org.grayrabbit.cms.dao.content.ContentDao;
import org.grayrabbit.cms.entity.Category;
import org.grayrabbit.cms.entity.OperLog;
import org.grayrabbit.cms.service.category.CategoryService;
import org.grayrabbit.cms.util.FilePathSptUtil;
import org.grayrabbit.cms.vo.category.CategoryBean;
import org.grayrabbit.cms.vo.content.ContentBean;
import org.grayrabbit.dao.util.Page;
import org.grayrabbit.service.impl.GenericServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * <b>OperLog</b>的service实现类，事务加此处：





 * @version 1.0,创建时间: 2011-05-16 14:38:49  
 */
@Service
@Transactional
public class CategoryServiceImpl extends GenericServiceImpl implements CategoryService {
	private static final Logger logger = LoggerFactory.getLogger(CategoryServiceImpl.class);
	/**
	 * 注入dao层：
	 */
	@Autowired
	@Qualifier("categoryDaoImpl")
	private CategoryDao categoryDao;
	
	@Autowired
	@Qualifier("contentDaoImpl")
	private ContentDao contentDao;
	
	/**
	 * 此方法执行时为只读事务：
	 * @see CategoryService#getOperLog(String)
	 */
	@Transactional(readOnly=true)
	public Category getCategory(final String categoryId){
		Category category = categoryDao.findById(categoryId);
		categoryDao.initialize(category);
		categoryDao.initialize(category.getSite());
		categoryDao.initialize(category.getCategory());
		return category;
	}
	
	@Transactional(readOnly=true)
	public  Category loadCategory(final String categoryId){
		return categoryDao.findById(categoryId);
	}
	
	/**
	 * 根据序号查询记录
	 * @see CategoryService#getOperLog(String)
	 */
	@Transactional(readOnly=true)
	public List<Category> findByOrd(final Integer ord, CategoryBean categoryBean){
		return categoryDao.findByOrd(ord,categoryBean);
	}
	/**
	 * @see CategoryService#delete(String)
	 */
	@Transactional
	public void delete(final Category category) {
		categoryDao.makeTransient(category);
	}
	
	/**
	 * @see CategoryService#save(OperLog)
	 */
	@Transactional
	public void save(final Category category) {
		categoryDao.makePersistent(category);		
	}
	/**
	 * 检查栏目名称唯一性
	 * @param role
	 * @return
	 */
	public Boolean checkNameUnique(String categoryName,String parentId,String siteId,String catname){
		return categoryDao.checkNameUnique(categoryName,parentId,siteId,catname);
	}
	/**
	 * 此方法执行时为只读事务：
	 * @see CategoryService#getPage(CategoryBean)
	 */
	@Transactional(readOnly=true)
	public Page<Category> getPage(final CategoryBean categoryBean){
		Page<Category> page =  new Page<Category>();
		page.setTotal(categoryDao.count(categoryBean));
		page.setResult(categoryDao.findByQc(categoryDao.assembly(categoryBean)));
		return page;
	}

	/**
	 * 此方法执行时为只读事务：
	 * @see CategoryService#list(Page, CategoryBean)
	 */
	public void list(Page<Category> page, CategoryBean categoryBean) {
		if(page==null)
			return;
		if(page.isAutoCount()){
			page.setTotal(categoryDao.count(categoryBean));
		}
		page.setResult(categoryDao.findByPage(page,categoryBean));
		for(int i=0;i<page.getResult().size();i++){
			page.getResult().get(i).getContents().size();
		}
	}
	/**
	 * 此方法执行时为只读事务：
	 * @see CategoryService#listNumCount(Page, CategoryBean)
	 */
	public void listNumCount(Page<Category> page, CategoryBean categoryBean) {
		if(page==null)
			return;
		if(page.isAutoCount()){
			page.setTotal(categoryDao.count(categoryBean));
		}
		List<Category> listcontents= categoryDao.findByPage(page,categoryBean);
		int methidtop=0;
		for(int i=0;i<listcontents.size();i++){
			int contentNum=0;
			String id=listcontents.get(i).getCategoryId();
			methidtop=contentNumCount(id,contentNum);
			listcontents.get(i).setContentNum(methidtop);
		}
		page.setResult(listcontents);
	}
	/**
	 * 统计栏目文章的数量（参数id，contentNum）
	 */
	public int contentNumCount(String id,int contentNum){
		int  methid=0,add=0;
		List<Category> list =findByParentId(id, null);
		if(list.size()==0){
			ContentBean cb = new ContentBean();
			cb.setCategory(getCategory(id));
			int endid=contentDao.count(cb);
			getCategory(id).setContentNum(endid);
			return endid;
		}
		for(int i=0;i<list.size();i++){
			String cid=list.get(i).getCategoryId();
			methid=contentNumCount(cid,contentNum);
			add=add+methid;
			list.get(i).setContentNum(methid);
		}
		contentNum=contentNum+add;
		return contentNum;
	}
	
	/**
	 * 查询所有记录
	 * @return 
	 */
	public List<Category> findALL(CategoryBean categoryBean) {
		return categoryDao.findByPage(categoryBean);
	}
	/**
	 * 根据父Id查询记录（参数parentId，bean）
	 * @param siteBean
	 * @return 
	 */
	public List<Category> findByParentId(String parentId, CategoryBean categoryBean){
		return categoryDao.findByParentId(parentId,categoryBean);
	}
	/**
	 * 根据站点ID查询栏目
	 * @param siteId
	 * @return
	 */
	public List<Category>findBySiteId(String siteId){
		return categoryDao.findBySiteId(siteId);
	}
	/**
	 * 根据主键id列删除，批量删除OperLog
	 * @see CategoryService#delete(String[])
	 */
	public void delete(final String[] key) {
		int i =0;
		for(String id : key){
			categoryDao.makeTransient(categoryDao.findById(id));
			i++;
			if(i==MAX_CLEAR)
				categoryDao.clear();
		}
		
	}
	/**
	 * 批量启用栏目
	 * @param keys
	 */
	public void enable(String[] keys){
		if(keys!=null){
			for(String str: keys){
				Category a=categoryDao.findById(str);
				a.setCategoryStatus(true);
				categoryDao.makePersistent(a);
			}
		}
		
	}
	/**
	 * 批量禁用栏目
	 * @param keys
	 */
	public void disable(String[] keys){
		if(keys!=null){
			for(String str:keys){
				Category a=categoryDao.findById(str);
				a.setCategoryStatus(false);
				categoryDao.makePersistent(a);
			}
		}
	}
	/**
	 * 查询全部记录列表
	 * @return
	 */
	public List<Category>catList(String parentId,String siteId){
		return categoryDao.catList(parentId,siteId);
	}
	public List<Category> allCatList(String siteId) {
		return categoryDao.tailEndList(siteId);
	}
	/**
	 *叶子接点栏目列表
	 * @return
	 */
	public List<Category> tailEndList(String siteId){
		List<Category> cateList = categoryDao.tailEndList(siteId);
		List<Category> childList=new ArrayList<Category>(); 
		for(Category item:cateList){
			List<Category> obj = initCategory(item);
			for(Category items:obj){
				childList.add(items);
			}
		}
		for(Category t:childList){
			cateList.add(t);
		}
		List<Category> tailEndList=new ArrayList<Category>(); 
		for(Category item:cateList){
			List<Category> obj = categoryDao.findByParentId(item.getCategoryId(),null);
			if(obj!=null&&obj.size()>0){
				
			}else{
				tailEndList.add(item);
			}
		}
		return tailEndList;
	}
	
	private List<Category> initCategory(Category item){
		List<Category> obj = categoryDao.findByParentId(item.getCategoryId(),null);
		List<Category> childList=new ArrayList<Category>(); 
		if(obj!=null&&obj.size()>0){
			for(Category item2:obj){
				List<Category> items = initCategory(item2);
				for(Category item3:items){
					childList.add(item3);
				}
			}
		}
		for(Category t :childList){
			obj.add(t);
		}
		return obj;
	}
		
	public List<Category> ftlFindCat(String[] catIds,String[] siteIds){
		try { 
			return categoryDao.findCat(catIds,siteIds);		 
		} catch (Exception e) {
			logger.error("栏目查询异常", e);
		}
		return new ArrayList<Category>();
	}

	public List<Category> ftlFindSonCat(String catId){
		try {
			return categoryDao.ftlFindSonCat(catId);	
		} catch (Exception e) {
			logger.error("栏目查询异常", e);
		}
		return new ArrayList<Category>();		 
	}
	
	/**
	 * 依照ID查找  并且初始化可用的子栏目
	 */
	public Category ftlFindCatInitUsableSons(String catId,int count){
		try {			
			Category category = categoryDao.findById(catId);
			List<Category> list = ftlFindSonCat(catId);
			List<Category> limit = new ArrayList<Category>(); 
			if(count==0 || list.size()<count){
				limit=list;
			}else{
				for(int i=0; i<count;i++){
					limit.add(list.get(i));
				}
			} 
			category.getCategories().clear();		
			category.getCategories().addAll(limit);
			return category;
		} catch (Exception e) {
			logger.error("栏目查询异常", e);
		}
		return new Category();
	}	
	
	@Transactional(readOnly=true)
	public Category findCatById(String catId){ 
		Category category = categoryDao.findById(catId); 
		categoryDao.initialize(category.getCategory());
		categoryDao.initialize(category.getSite());
		return  category;
	}
	
	@Transactional(readOnly=true)
	public Category ftlFindCatById(String catId){ 
		try {
			if(StringUtils.isEmpty(catId)) 
				throw new IllegalArgumentException("the argument 'catId' is null,error!");
			Category category = categoryDao.findById(catId);
			categoryDao.initialize(category.getCategories());
			return category;
		} catch (Exception e) {
			 logger.error("栏目查询异常", e);
		}
		return new Category();
	}
	
	@Transactional(readOnly=true)
	public String ftlCatCrumbs(String catId,String type,String text,String cssClass){ 
		if(StringUtils.isBlank(catId) || StringUtils.isBlank(type)) {
			logger.error("the argument 'catId' or 'type' is null,error!");
			return "";
		}
		try{
			Category cat = categoryDao.findById(catId);
			categoryDao.initialize(cat.getSite());
			categoryDao.initialize(cat.getCategory());
			
			StringBuffer sb = new StringBuffer();
			loadAHerf(sb, cat,  type, text, cssClass);
			categoryDao.clear();
			return sb.toString();
		}catch(Exception e){
			logger.error("获取栏目异常",e);
		}
		return "";
	}
	
	public String catUrlLeftTree(String catId,String type,String text,String cssClass){ 
		if(StringUtils.isBlank(catId) || StringUtils.isBlank(type)) {
			logger.error("the argument 'catId' or 'type' is null,error!");
			return "";
		}
		try{
			 
			Category cat = categoryDao.findById(catId); 
			categoryDao.initialize(cat.getSite());
			categoryDao.initialize(cat.getCategory());
			
			StringBuffer sb = new StringBuffer();
			if(cat.getIsLink() == null  || cat.getIsLink().booleanValue() ){
				loadAHerf(sb, cat,type, text, cssClass);				
			}else{
				if(DBInitId.ASSOCIATORS_ID.equals(cat.getCategoryId())){
					sb.append("<a  href=\"")
					  .append(FilePathSptUtil.CMS_VISIT_CONTEXT_PATH);
					if(!FilePathSptUtil.CMS_VISIT_CONTEXT_PATH.endsWith("/")){
					    sb.append("/");
					}

					sb.append("front/esp/enterprise-showenterprises.action")
					  .append("\" ");

					if(StringUtils.isNotBlank(cssClass)){
						sb.append(" class=\"");
						sb.append(cssClass);
						sb.append("\" ");
					}
					sb.append(" >");
					if("none".equals(text)){
						sb.append("");
					}
					else if(StringUtils.isNotBlank(text)){
						sb.append(text.trim());
					}
					else{			
						sb.append(cat.getCatName());
					}
					sb.append("</a>");
				}else{
					sb.append("<span  id=\"")
					  .append(cat.getCategoryId())
					  .append("\">")
					  .append(cat.getCatName())
					  .append("</span>");					
				}
				
			}	
			categoryDao.clear();
			return sb.toString();
		}catch(Exception e){
			logger.error("获取栏目异常",e);
		}
		return "";
	}
	
	private StringBuffer loadAHerf(StringBuffer sb,Category cat,String type,String text,String cssClass){
		sb.append("<a hidefocus=\"true\" href=\"")
		  .append(cat.getSite().getSiteDomain());
		if(!cat.getSite().getSiteDomain().endsWith("/")){
		    sb.append("/");
		}
		sb.append(Category.CATEGORY_PATH);
		Category c = loadCatCrumbs(cat, sb);
		if("tree".equalsIgnoreCase(type)){
			if(cat.getTreeIndexLink()!=null && cat.getTreeIndexLink().booleanValue()){
				sb.append("/index.html\"");
			}else{
				sb.append("/list.html\"");
			}
		}else{			
			sb.append("/"+type+".html\"");
		}
		if(StringUtils.isNotBlank(cssClass)){
			sb.append(" class=\"");
			sb.append(cssClass);
			sb.append("\"");
		}
		sb.append("  id=\"").append(c.getCategoryId()).append("\" ");
		sb.append('>');
		if("none".equals(text)){
			sb.append("");
		}
		else if(StringUtils.isNotBlank(text)){
			sb.append(text.trim());
		}
		else{			
			sb.append(c.getCatName());
		}
		sb.append("</a>");
		
		return sb;
	}
	
	private  Category loadCatCrumbs(Category c,StringBuffer sb){
		if(c!=null && c.getCategory()!=null && 
				StringUtils.isNotBlank(c.getCategory().getCategoryId())){
			categoryDao.initialize(c.getCategory().getCategory());		
			loadCatCrumbs(c.getCategory(), sb);
		} 
		sb.append("/"+c.getCatSimpleName());
		return c;
	}
	/**
	 * 根据站点ID获取栏目
	 * @param list
	 * @param cuttentCatIndex
	 * @param max
	 * @return
	 */
	public List<String> findCatIdsBySiteId(List<String> siteIds, int currentCatIndex,	int max){
		return categoryDao.findPublishCategoryBySiteId(siteIds,currentCatIndex,max);
	}
	/**
	 * 获取栏目下的文章数
	 * @param list
	 * @return
	 */
	public int countContentByCats(List<String> list){
		int count = 0;
		for(String catId:list){
			Category cat = categoryDao.findById(catId);
			ContentBean contentBean = new ContentBean();
			contentBean.setCategory(cat);
			count+=contentDao.countAllByPublish(contentBean);
		}
		return count;
	}
	/**
	 * 获取栏目下增量的文章数
	 * @param list
	 * @return
	 */
	public int countMoreContentByCats(List<String> list){
		int count = 0;
		for(String catId:list){
			Category cat = categoryDao.findById(catId);
			CategoryBean catBean = new CategoryBean();
			ContentBean contentBean = new ContentBean();
			catBean.setCategoryId(catId);
			if(cat.getIsAudit()!=null&&cat.getIsAudit().booleanValue()){
				contentBean.setContentStatus(DictionaryStaticValues.CONTENT_STATUS_SUCCESS);
			}else{
				contentBean.setContentStatus(DictionaryStaticValues.CONTENT_STATUS_NEW);
			}
			contentBean.setCategory(catBean);
			contentBean.setMaxPublishTime(new Date());
			count+=contentDao.count(contentBean);
		}
		return count;
	}

	public String[] ftlFindFamilyLine(String id) {
		try {
			List<String>  list = new ArrayList<String>();
			Category c= categoryDao.findById(id);
			initUpCat(c,list);
			list.add(c.getCategoryId()); 
			String[] arr = new String[list.size()];		
			return list.toArray(arr);
		} catch (Exception e) {
			logger.error("父IDS 查询异常", e);
		}		 
		return new String[0];
	}
	
	private void initUpCat(Category c,List<String>  list){
		if(c.getCategory() != null){
			categoryDao.initialize(c.getCategory());
			initUpCat(c.getCategory(),list);
			list.add(c.getCategory().getCategoryId()); 
		}
	}
	
	public boolean ftlIsFamily(String id,String topId){
		boolean flag =false;
		try {			
			if(StringUtils.isBlank(id) || StringUtils.isBlank(topId)) 
				throw new IllegalArgumentException("the argument 'id' or 'topId' is null,error!");
			Category top= categoryDao.findById(topId);
			if(top==null || top.getCategory()!=null)
				throw new Exception(" id为   'topId' 的栏目不是顶级栏目");
			Category c= categoryDao.findById(id);
			List<String>  list = new ArrayList<String>();
			ftlFindFather(c, list);
			if(list.isEmpty() || list.size()>1){
				throw new IllegalArgumentException("查询结果异常");
			}else{
				if(topId.equals(list.get(0))) flag=true;				 
			}		
		} catch (Exception e) {
			logger.error("查询异常",e);
		}
		return flag;
	}
	
    private void ftlFindFather(Category c ,List<String>  list){
    	if(c==null)  return;
    	if(c.getCategory() != null){
    		categoryDao.initialize(c.getCategory());
    		ftlFindFather(c.getCategory(), list);
    	}else {
    		list.add(c.getCategoryId());
    	}
    }
	

	public Boolean checksimplename(String categoryName, String siteId,
			String catSimpleName) {
		
		return null;
	}

	public Boolean checksimpleunique(String catSimpleName, String siteId,
			String catoldSimpleName) {
		return categoryDao.checksimpleunique(catSimpleName, siteId, catoldSimpleName);
	}
	/*
	*查找栏目子节点
	*/
	public String findByCategoryChildIds(String id){
		String childId = "";
		List<Category> list =findByParentId(id, null);
		for(int j=0;j<list.size();j++){
			childId=childId+findByChilds(childId,list.get(j).getCategoryId())+list.get(j).getCategoryId()+"@";
		}
		
		return childId;
	}
	/*
	*递归查找栏目子节点
	*/
	public String findByChilds(String childIds,String id){
		List<Category> list = findByParentId(id, null);
		if(list.size()==0){
			return "";
		}
		for(int j=0;j<list.size();j++){
			childIds=childIds+findByChilds(childIds,list.get(j).getCategoryId())+list.get(j).getCategoryId()+"@";
		}
		list.clear();
		return  childIds;
	}
    /** 依据顶级栏目查找出所有的可以展示的子孙栏目*/ 
	public List<Category> ftlFindSonsByTopCatId(String catId,String[] hiddenIds){
		try { 
			if(StringUtils.isBlank(catId)) 
				throw new IllegalArgumentException("the argument 'catId' is null,error!");			 
			List<Category>  list = categoryDao.ftlFindByParentId(catId);
			filInitSons(list,hiddenIds);		
			return  list;
		} catch (Exception e) {
			logger.error("查询子栏目异常", e);
			return new ArrayList<Category>();
		}
	}
	
    /**初始化 某栏目下 可以展示的 sons*/
	private void filInitSons(List<Category> list,String[] hiddenIds ){
		if(list == null || list.isEmpty())  return ;
		for(Category c : list){
			if(hasCategoryId(c.getCategoryId(), hiddenIds)) continue;
			List<Category>  sons = categoryDao.ftlFindByParentId(c.getCategoryId());			 
			c.setSons(sons); 
			filInitSons(sons, hiddenIds);		 
		}
	}
	
	private boolean hasCategoryId(String id ,String[] catIds){
		if(catIds != null && !ArrayUtils.isEmpty(catIds)){ 
			for(String d :catIds){
				if(d.equals(id)) return true; 
			}
		}
		return false;
	}
	
	/**
	 * 获取父路径
	 * @param obj
	 * @return
	 */
	public String getParentPath(Category obj){
		String path = obj.getCatSimpleName();
		if(obj.getCategory()!=null){
			if(getCategory(obj.getCategory().getCategoryId())!=null){
				path=FilePathSptUtil.padRightSpt(getParentPath(getCategory(obj.getCategory().getCategoryId())))+path;
			}
		}
		return path;
	}

	public String ftlCatHref(String catId,String catName,String area, String type) {
		if(StringUtils.isBlank(type)){
			logger.error("the argument  'type' is null,error!");
			return "###";
		}
		try{
			Category cat = null;
			if(StringUtils.isNotBlank(catId)) {			
				cat = categoryDao.findById(catId); 
			}else{
				if(StringUtils.isNotBlank(catName)) {	
					if(StringUtils.isNotBlank(area)){						 
						cat = categoryDao.findByNameAndSiteArea(catName,area); 
					}else{
						logger.error("the argument  'area' is null,error!");
						return "###";
					}
				}else{
					logger.error("the argument  'catName' is null,error!");
					return "###";
				}
			}
			categoryDao.initialize(cat.getCategory());
			categoryDao.initialize(cat.getSite()); 
			StringBuffer domain  = new StringBuffer();
			domain.append(cat.getSite().getSiteDomain());
			if(!cat.getSite().getSiteDomain().endsWith("/")){
				domain.append("/");
			}
			domain.append(Category.CATEGORY_PATH);			
			StringBuffer sb = new StringBuffer();
			sb.append(cat.getCatSimpleName()+"/");
			while(cat!=null && cat.getCategory()!=null&&StringUtils.isNotBlank(cat.getCategory().getCategoryId())){
				cat = ftlFindCatById(cat.getCategory().getCategoryId());
				sb.insert(0,cat.getCatSimpleName()+"/");
			} 			
			sb.append(type+".html");
			domain.append("/").append(sb);
			categoryDao.clear();
			return domain.toString();
		}catch(Exception e){
			logger.error("获取栏目异常",e);
		}
		return "";
	}
	
	public List<Category> ftlFindTopCategory(String siteid){
		return categoryDao.ftlFindTopCategory(siteid);
	}
	/**
	 * 得到顶级栏目
	 * @param siteId
	 * @return
	 */
	public List<Category> getTopCategory(String siteId){
		return categoryDao.getTopCategory(siteId);
	}
	public List<Category> ftlFindCategory(String siteid, String categoryid, long[] limit){
		return categoryDao.ftlFindCategory(siteid, categoryid, limit);
	}
	
	/**
	 * 通过子栏目Id得到顶级父栏目
	 */
	public Category ftlFindTopParentCategory(String id){
		try{
			if(StringUtils.isBlank(id)){
				throw new IllegalArgumentException("the argument 'categoryId' is null,error!");
			}
			Category category = categoryDao.findById(id);
			while(getParentCat(category)!=null){
				category = getParentCat(category);
			}
			return category;
		}catch(Exception e){
			logger.error("获取栏目异常",e);
		}
		return new Category();
	}
	private Category getParentCat(Category cat){
		categoryDao.initialize(cat.getCategory());
		return cat.getCategory();
	}
	
	/**
	 * 通过站点Id得到顺序第一的栏目
	 */
	public Category ftlFindHomeCategory(String siteId) {
		return categoryDao.getHomeCategory(siteId);
	}

}